#include<stdio.h>
#include<string.h>
#include<stdlib.h>
#include<math.h>
// int main()
// {
//   printf("hello bit");
//   //重新在本地保存和提交

// }

/***********************************************************************/
//逆序字符串函数,并打印1、框架2、函数具体实现
// void Rev_String(char* Str,int length)
// {
//     int left = 0;
//     int right = length - 1;
//     while(left<right)
//     {
//       char temp = *(Str+left);
//       *(Str+left) = *(Str+right);
//       *(Str+right) = temp;
//       left++;
//       right--;
//     }
// }
// int main()
// {
//   char arr[10001] = {0};
//   printf("输入字符串：");
//   gets(arr);
//   int length = strlen(arr);
//   Rev_String(arr,length);
//   printf("逆序字符串：");
//   // for(int i = 0;i<length;i++)
//   // {
//   //   printf("%c",arr[i]);
//   // }
//   printf("%s",arr);
// }

/***********************************************************************/ 
//求Sn=a+aa+aaa+aaaa+aaaaa,前n项之和
//a,传递a
//aaaa = 1000*a +100*a+10*a+a

// int fun(int a,int n)
// {
//   int sum = 0;
//   for(int i = 1;i<=n;i++)
//   {
//     sum += a*pow(10,i-1);
//   }
//   return sum;
// }
// int Sn(int a,int n)
// {
//   int sum = 0;
//   for(int i = 1;i<=n;i++)
//   {
//     sum += fun(a,i);
//   }
//   return sum;
// }

// int main()
// {
//   int a = 0,n=0;
//   printf("请输入a和n:");
//   scanf("%d %d",&a,&n);
//   int SUM = Sn(a,n);
//   printf("结果是:%d",SUM);
// }

//更加简单的方法
// int main()
// {
//   int a = 0,n=0;
//   printf("请输入a和n:");
//   scanf("%d %d",&a,&n);
//   int SUM = 0,k = 0;
//   for(int i = 0;i<n;i++)
//   {
//     k=k*10+a;
//     SUM += k;
//   }
//   printf("结果是:%d",SUM);
// }
/***********************************************************************/


// //求出1~10000的所有的水仙花数，封装成函数的形式
// //1、求出几位数2、求出每一位3、再判断
// //使用三个函数
// //1、求出几位数
// // int Count(int a)
// // {
// //   int count = 0;
// //   while(a !=0)
// //   {
// //     count++;
// //     a /= 10;
// //   }
// //   return count;
// // }
// // //2、求出每一位的同时判断
// // int is_narcissistic(int a)
// // {
// //   int n = Count(a);
// //   int temp = a;
// //   int sum = 0;
// //   while(a)
// //   {
// //     sum += pow(a%10,n);
// //     a/=10;
// //   }
// //   return temp == sum;//判断是否相等，直接reurn这个判断
// // }

// // int main()
// // {
// //   int a;
// //   for(a = 1; a < 100000; a++)
// //   {
// //       if(is_narcissistic(a))
// //     {
// //       printf("%d是水仙花数\n",a);
// //     }
// //   }
// //   return 0;
// // }
/***********************************************************************/

//打印对称的菱形
// int main()
// {
//   //上部分
//   int height = 7;
//   for(int i =0;i<height;i++)
//   {
//     for(int j = 0;j<height-i-1;j++)
//     {
//       printf(" ");
//     }
//     for(int j = 0;j<2*i+1;j++)
//     {
//       printf("*");
//     }
//     printf("\n");
//   }
//   //下部分
//   for(int i=0;i<height-1;i++)
//   {
//     for(int j=0;j<i+1;j++)
//     {
//       printf(" ");
//     }
//     for(int k=0;k<2*(height-i-1)-1;k++)
//     {
//       printf("*");
//     }
//     printf("\n");
//   }
// }
/***********************************************************************/

//喝汽水问题。一瓶汽水1块，2个空瓶子换一瓶汽水，20块能喝多少汽水
//
// int main()
// {
//   int money = 20;
//   int total = money;
//   int bootles = money;
//   while(bootles>=2)
//   {
//     total = total +bootles/2;
//     bootles = bootles/2 + bootles%2;//对于计算机图和理解除2
//   }
//   printf("%d",total);
// }
/***********************************************************************/

//I like beijing.  逆序成  beijing. like I
// void reverse_strings(char* str,int length,int start)
// {
//   int right = length;
//   int left = start;
//   char temp = 0;
//   while(left<right)
//   {
//     temp = *(str+right);
//     *(str+right) = *(str+left);
//     *(str+left) = temp;
//     left++;
//     right--;
//   }
// }
// int main()
// {
//   char arr[]="I like beijing.";
//   int sz = sizeof(arr)/sizeof(arr[0]);
//   //逆序整个字符串
//   reverse_strings(arr,sz-2,0);
//   //逆序单词
//   int count = 0;
//   for(int i = 0;i<sz;i++)
//   {
//     if(arr[i] == ' ' || arr[i] == '\0')
//     {
//       reverse_strings(arr,i-1,count); 
//       count = i+1;
//     }
//   }
//   for(int i = 0;i<sz;i++)
//   {
//     printf("%c",arr[i]);
//   }
// }

//另一种版本，思路差不多
// void reverse_s(char*left,char*right)
// {
//   while(left<right)
//   {
//     char temp = *left;
//     *left = *right;
//     *right = temp;
//     left++;
//     right--;
//   }
// }
// int main()
// {
//   char arr[100] = "I like beijing.";
//   //逆序整个字符串
//   reverse_s(arr,arr+strlen(arr)-1);
//   //printf("%s\n",arr);测试成功
//   //逆序单词
//   char* start = arr;
//   char* end = arr;
//   while(*start != '\0')
//   {
//     while(*end != ' ' && *end != '\0')
//     {
//       end++;
//     }
//     reverse_s(start,end-1);
//     if(*end != '\0')
//     {
//       end++;
//     }
//     start = end;
//   }
//   printf("%s\n",arr);
// }

/***********************************************************************/
//模拟strcopy函数
// char* my_strcpy(char* dest, const char* source)
// {
//     while(*source != '\0')
//     {
//       *dest = *source;
//       dest++;
//       source++;
//     }
//     *dest = *source;
// }

//版本2
// void my_strcpy(char* dest, const char* source)
// {
//     //加入assert
//     assert(dest != NULL && source != NULL);
//     while(*dest++ = *source++)
//     {
//       ;
//     }
// }
// int main()
// {
//     char src[10] = "hello bit";
//     char dest[10];
//     my_strcpy(dest, src);
//     printf("%s\n", dest);
//     return 0;
// }

/***********************************************************************/
//将数组里面的数区分为奇数和偶数，奇数放前面，偶数放后面
// int main()
// {
//   int arr[15] = {1,2,3,4,5,6,7,8,9,10,11,12,13,14,15};
//   int left = 0;
//   int right = sizeof(arr)/sizeof(arr[0])-1;
//   while(left < right)
//   {
//     //左边找奇数
//     while((arr[left]%2 == 1)&&(left < right))//如果全部是奇数或者偶数，防止越界另加一个条件.在有效范围内查找
//     {
//       left++;
//     }
//     while((arr[right]%2 == 0)&&(left < right))
//     {
//       right--;
//     }
//     if(left < right)
//     {
//       int temp = arr[left];
//       arr[left] = arr[right];
//       arr[right] = temp;
//     }
//   }
//   for(int i = 0;i<15;i++)
//   {
//     printf("%d ",arr[i]);
//   }
// }

/***********************************************************************/
// //有序序列合并
// int main()
// {
//   int arr1[100] = {1,2,3,4,5,6};
//   int arr1_size = 6;
//   int arr2[100] = {11,22,33,44,55,66,77,88};
//   int arr2_size = 8;
//   //合并成有序序列并且打印
//   int i = 0, j = 0;
//   while(i < arr1_size && j < arr2_size)
//   {
//     if(arr1[i] < arr2[j])
//     {
//       printf("%d ",arr1[i]);
//       i++;
//     }
//     else
//     {
//       printf("%d ",arr2[j]);
//       j++;
//     }
//   }
//   if(i<arr1_size)//剩余的
//   {
//     for(;i<arr1_size;i++)
//     {
//       printf("%d ",arr1[i]);
//     }
//   }
//   if(j<arr2_size)//剩余的
//   {
//     for(;j<arr2_size;j++)
//     {
//       printf("%d ",arr2[j]);
//     }
//   }
// }

/***********************************************************************/
//指针总结
//1、字符指针
// char* p = "hello world";///字符串常量，只读内存区，无法通过指针修改；将其首地址赋值给字符指针
// char arr[100]= "hello world";//两者是不同的：将字符串复制到栈区给数组
// //2、指针数组（数组的首地址---数组名，使用指针来接收；特例：指针数组，由于数组名本就是一级指针的地址，所以使用二级指针来接收
// char* arr2[10] = {NULL};//arr2是一级指针的地址
// char** parr = arr2;//指针数组的首地址使用二级指针接收，数组名
// //3、数组指针（数组的地址---&数组名，需要使用数组指针来接收）
// char arr3[10] = {0};
// char* parr3 = arr3;//数组的首地址，数组名
// char (*parr33)[10] = &arr3;//数组的地址，&数组名

// char* arr4[10] = {NULL};
// char* (*parr4)[10] = &arr4;//指针数组的地址使用数组指针来接收，&数组名
// //4、数组指针数组
// char (*parr5[10])[10] = {NULL};//存放数组指针的数组



// //函数指针
// int test(const char* str)
// {
//   printf("%s\n",str);
// }

// int main()
// {
//   int (*pf)(const char*) = test;
//   pf("hello world");
// }

// //使用typedef简化该函数声明;回顾：typedef unsigned int uint;//重新定义类型
// //typedef void(*)(int) fp;---error不是这么定义的

// typedef void(*pf_t)(int);//把函数指针类型void(*)(int) 重新定义为pf_t（从此pf_t就是一种函数指针类型）

// void(*signal(int,void(*)(int)))(int);  //简化成如  下形式:pf_t signal(int,pf_t);


// /***********************************************************************/
// //函数指针应用：回调函数
// int add(int a,int b)
// {
//     return a+b;
// }
// int sub(int a,int b)
// {
//     return a-b;
// }
// int mul(int a,int b)
// {
//     return a*b;
// }
// int Div(int a,int b)
// {
//     return a/b;
// }
// // int calc(int (*pf_t)(int,int))//回调函数
// // {
// //     return pf_t(10,5);
// // }
// // int main()
// // {
// //     printf("%d\n",calc(add));
// //     printf("%d\n",calc(sub));
// //     printf("%d\n",calc(mul));
// //     printf("%d\n",calc(Div));
// // }
// /***********************************************************************/
// //函数指针数组
// int (*arr[])(int,int) = {NULL,add,sub,mul,Div};
// int main()
// {
//     printf("%d\n",arr[1](10,5));
// }
// //将该函数指针数组封装成函数
// int calc2(int (*arr[])(int,int),int index,int a,int b)
// {
//     return arr[index](a,b);
// }
// // //调用函数
// // int main()
// // {
// //     printf("%d\n",calc2(arr,1,10,5));
// // }


// /***********************************************************************/
// //函数指针数组的指针

// int     (*    (*pparr)[]     )      (int,int) = &arr;//函数指针数组，还是个数组，按照原来的方法直接加个*号
// //括号指针；指向数组；类型是函数指针


/***********************************************************************/
//使用qsort函数来排序结构体数据
// struct student
// {
//     char name[10];
//     int age;
//     float score;
// };

// int com_stu_by_first_char(const void* e1)
// {
//     printf("%c\n",((struct student*)e1)->name[0]);
    
// }
// int cmp_stu_by_name(const void* e1,const void* e2)
// {
    
//     return strcmp(((struct student*)e1)->name,((struct student*)e2)->name);//强制类型转换之后还要加括号在->访问
// }


// int cmp_stu_by_age(const void* e1,const void* e2)
// {
    
//     return ((struct student*)e1)->age - ((struct student*)e2)->age;
// }



// void my_swap(char* a,char* b,int width)
// {
//     char tmp;
//     for(int i = 0;i < width;i++)//一个字节一个字节的交换
//     {
//         tmp=*a;
//         *a=*b;
//         *b=tmp;
//         a++;
//         b++;
//     }   
// }   
// void my_qsort(void* base,int sz,int width,int (*cmp)(const void* e1,const void* e2))//基于冒泡排序的思想
// {
//     int i = 0;
//     //趟数为sz-1
//     for(i = 0; i < sz-1; i++)
//     {
//         int j = 0;
//         for(j = 0; j < sz-1-i; j++)
//         {
//             char* base_char = (char*)base;
//             if(cmp(base_char+j*width,base_char+(j+1)*width)  > 0)//最小单位来查找元素
//             {
//                 my_swap(base_char+j*width,
//                         base_char+(j+1)*width,
//                         width);
//             }
//         }
//     }
// }
// int main()
// {
//     struct student arr[3] = //如果这里设置成5个元素，qsort就会把后面的空元素也比较一下，所以会显示name数组为0
//     {
//         {"zhangsan",15,90.5},
//         {"lisi",11,90},
//         {"wangwu",18,89.5},
//     };
//     int sz = sizeof(arr)/sizeof(arr[0]);
//     int width = sizeof(arr[0]);
//     // com_stu_by_first_char(arr);
//     // com_stu_by_first_char(arr+1);
//     // com_stu_by_first_char(arr+2);
//     // 排序前输出
//     //qsort(arr,sz,width,cmp_stu_by_name);
//     //my_qsort(arr,sz,width,cmp_stu_by_name);
//     my_qsort(arr,sz,width,cmp_stu_by_age);
//     printf("\n排序后:\n");
//     for(int i = 0; i < 3; i++) 
//     {
//     printf("姓名: %s, 年龄: %d, 分数: %.1f\n", 
//     arr[i].name, arr[i].age, arr[i].score);
//     }
// }

/***********************************************************************/
// int main()
// {
//     char *p = "abcdef";
//     printf("%p\n",&p);
//     printf("%p\n",&p+1);//确实是相差一个指针的长度
// }
/***********************************************************************/
//二维数组的数组名理解
// int main()
// {
//     int a[3][4] = {0};
//     printf("%d\n",sizeof(a));//48.数组名单独放在sizeof内部就代表整个数组大小
//     printf("%d\n",sizeof(a[0][0]));//4.
//     printf("%d\n",sizeof(a[0]));//16.a[0]是指向第一行首元素的数组指针---a[0]是数组名
//     printf("%d\n",sizeof(a[0]+1));//4/8
//     printf("%d\n",sizeof(*(a[0]+1)));//4
//     printf("%d\n",sizeof(a+1));//4/8
//     printf("%d\n",sizeof(*(a+1)));//16
//     printf("%d\n",sizeof(&a[0]+1));//4/8
//     printf("%d\n",sizeof(*(&a[0]+1)));//16
//     printf("%d\n",sizeof(*a));//16
//     printf("%d\n",sizeof(a[3]));//16---sizeof只关注类型。a[3]是数组名，所以sizeof(a[3])和sizeof(a[0])一样，不会真的访问第四行----不管了
// }


/***********************************************************************/
//模拟实现strlen
//计数器方法
// int my_strlen(char* str)
// {
//     int count = 0;
//     while(*str != '\0')
//     {
//         count++;
//         str++;
//     }
//     return count;
// }
// //指针减去指针方法
// int my_strlen2(char* str)
// {
//     char* p = str;
//     while(*p != '\0')
//     {
//         p++;
//     }
//     return p-str;
// }
// int main()
// {
//     char* str = "abcdef";
//     printf("%d\n",my_strlen(str));
//     printf("%d\n",my_strlen2(str));
// }

/***********************************************************************/
//模拟实现strcpy
// char* my_strcpy(char* dest,const char* src)//返回目标空间地址
// {
//     assert(dest && src);
//     char* ret = dest;
//     while(*dest++ = *src++)
//     {;
//     }
//     return ret;
// }
// //验证
// int main()
// {
//     char str1[10] = {0};
//     char str2[10] = "abcdef";
//     my_strcpy(str1,str2);
//     printf("%s\n",str1);
// }

/***********************************************************************/
//模拟实现strcmp
// int my_strcmp(const char* str1,const char* str2)
// {
//     assert(str1 && str2);
//     while(*str1 != '\0' && *str2 != '\0')
//     {
//         if(*str1 != *str2)
//         {
//             return *str1 - *str2;
//         }
//         str1++;
//         str2++;
//     }
//     return *str1 - *str2;
// }

/***********************************************************************/
//模拟实现strncat
// char* my_strncat(char* dest,const char* src,int n)//返回目标空间地址
// {
//     assert(dest && src);
//     char* ret = dest;
//     while(*dest)
//     {
//         dest++;
//     }
//     while(n-- && *src)
//     {
//         *dest++ = *src++;
//     }
//     return ret;
// }

/***********************************************************************/
//模拟实现strncmp
// int my_strncmp(const char* str1,const char* str2,int n)
// {
//     assert(str1 && str2);
//     while(*str1 != '\0' && *str2 != '\0' && n--)
//     {
//         if(*str1 != *str2)
//         {
//             return *str1 - *str2;
//         }
//         str1++;
//         str2++;
//     }
//     return *str1 - *str2;
// }

/***********************************************************************/
//模拟实现strstr
// char* my_strstr(const char* des,const char* sre)//返回子串地址
// {
//     const char* str1 = des;
//     const char* p = des;
//     const char* str2 = sre;
//     while(*p)
//     {
//         str1 = p;
//         str2 = sre;
//         while(*str1 && *str2 && *str1 == *str2)
//         {
//             str1++;
//             str2++;
//         }
//         if(*str2 == '\0')
//         {
//             return (char*)p;
//         }
//         p++;
//     }
//     return NULL;
// }

// int main()
// {
//     char str1[10] = "abccde";
//     char str2[10] = "ccd";
//     char* ret = my_strstr(str1,str2);
//     printf("%s\n",ret);
// }

//Next数组
// int get_next(char* str,int* next)//返回next数组---涉及数据结构，还有Kmp算法
// {
//     int i = 0;
//     int j = -1;
//     next[0] = -1;
//     while(str[i] != '\0')
//     {
//         if(j == -1 || str[i] == str[j])
//         {
//             i++;
//             j++;
//             next[i] = j;
//         }
//     }
// }

/***********************************************************************/
//strtok应用
// #include <string.h>
// int main()
// { 
//     const char* sep = "@."; 
//     char email[] = "<EMAIL>@lice.com";
//     char cp[20] = {0};
//     strcpy(cp,email);
//     char* ret = NULL;
//     for(ret = strtok(cp,sep);NULL != ret;ret = strtok(NULL,sep))//仅初始化第一次cp，其他都为空指针
//     {
//         printf("%s\n",ret);
//     }
// }

/***********************************************************************/
//模拟实现memcpy
// void* my_memcpy(void* dest,const void* src,size_t num)
// {
//     assert(dest && src);
//     void* ret = dest;
//     while(num--)
//     {
//         *(char*)dest = *(char*)src;
//         dest = (char*)dest + 1;
//         src = (char*)src + 1;
//     }
//}
/***********************************************************************/
//模拟实现memmove
// void* my_memmove(void* dest,const void* src,size_t num)
// {
//     void* ret = dest;
//     if(dest<src)
//     {
//         //从前往后拷贝
//         while(num--)//运行循环体的时候num已经被减去1了
//         {
//             *(char*)dest = *(char*)src;
//             dest = (char*)dest + 1;//
//             src = (char*)src + 1;
//         }
//     }
//     else
//     {
//         while(num--)
//         {
//             ((char*)dest)  [num] =  ((char*)src)  [num];
//         }
//     }
// }
// //验证
// int main()
// {
//     char str1[10] = "abcdef";
//     char str2[10] = "ABCDEF";
//     my_memmove(str1,str1+1,3);
//     printf("%s\n",str1);
// }
/***********************************************************************/
//作业
//1、输入一个整数，其中地奇数变为1，偶数变成0，最后输出这个数
// int change(int num)
// {
//     int sum = 0;
//     int i = 0;
//     while(num)
//     {
        
//         int bit = 0;
//         int tmp = num%10;
//         num /= 10;
//         if(tmp % 2 == 1)//奇数
//         {
//             bit = 1;
//             //sum += 1*pow(10,i-1);
//         }
//         else//偶数
//         {
//             bit = 0;
//             //sum += 0*pow(10,i-1);;
//         }
//         sum += bit*pow(10,i);
//         i++;
//     }
//     return sum;
// }
// int main()
// {
//     int num = 0;
//     printf("请输入一个整数：");
//     scanf("%d",&num);
//     printf("%d\n",change(num));
//     return 0;
// }

/***********************************************************************/
// 2、函数：旋转字符串
// void string_rotate(char* arr,int n)
// {
//     int len = strlen(arr);
//     //限制n在len的范围内
//     n %= len;
//     while(n--)//循环n次
//     {
//         //移动一个字符
//         char temp = arr[0];
//         memmove(arr,arr+1,len-1);
//         arr[len-1] = temp;
//     }
//}


//逆序字符串的方式，旋转字符串
// void reverse_string(char* left,char*right)
// {
//     while(left<right)
//     {
//         char temp = *left;
//         *left = *right;
//         *right = temp;
//         left++;
//         right--;
//     }
// }
// void string_rotate(char arr[],int n)
// {
//     int len = strlen(arr);
//     n %= len;//防止越界
//     reverse_string(arr,arr+n-1);//逆序左边n个
//     reverse_string(arr+n,arr+len-1);//逆序剩下的len-n个
//     reverse_string(arr,arr+len-1);//逆序整体，记得得到结果
// }

// int main()    
// {
//     char arr[6] = "abcde";
//     string_rotate(arr,2);
//     printf("%s\n",arr);
// }
/***********************************************************************/
// 3、查找递增的二维数组中的数字，并返回坐标值
// struct point
// {
//     int x;
//     int y;
// };

// struct point check_arr(int (* arr)[3],int col,int row,int k)//传递二维数组：数组指针，数组
// {
//     int x = 0;
//     int y =col-1;
//     struct point p = {-1,-1};
//     while(x<=row-1 && y>=0)
//     {
//         if(k>arr[x][y])
//         {
//             x++;
//         }
//         else if(k<arr[x][y])
//         {
//             y--;
//         }
//         else
//         {   
//             p.x = x;
//             p.y = y;
//             return p;
//         }
//     }
//     return p;
// }

// int check_arr(int (* arr)[3],int* row,int* col,int k)//传递二维数组：数组指针，数组
// {
//     int x = 0;
//     int y =*col-1;
//     while(x<=*row-1 && y>=0)
//     {
//         if(k>arr[x][y])
//         {
//             x++;
//         }
//         else if(k<arr[x][y])
//         {
//             y--;
//         }
//         else
//         {   
//             *row= x;
//             *col= y;
//             return 1;
//         }
//     }
//     return 0;
// }
// int main()
// { 
//     int a[3][3] = {1,2,3,4,5,6,7,8,9};
//     int k = 0;
//     printf("输入要查找的数：");
//     scanf("%d",&k);
//     //struct point lebal = check_arr(a,3,3,1);
//     //printf("%d %d",lebal.x,lebal.y);
//     int a1 = 3;
//     int b =3;
    
//     if(check_arr(a,&a1,&b,k))
//     {
//         printf("找到该数，坐标为：%d %d",a1,b);
//     }
//     else
//     {
//         printf("没有找到该数");
//     }
// }

/***********************************************************************/
//结构体内存对齐
// #include <stdio.h>
// #include <stddef.h>
// struct node
// {
//     char a;
//     int b;
//     char c;
//     char arr[10];
// };

// struct node2
// {
//     char a;
//     int b;
//     int arr[2];
// };
// int main()
// {
//     // printf("%d\n",sizeof(struct node));
//     // //offsefof
//     // printf("%d\n",offsetof(struct node,a));
//     // printf("%d\n",offsetof(struct node,b));
//     // printf("%d\n",offsetof(struct node,c));
//     // printf("%d\n",offsetof(struct node,arr));  
//     printf("%d\n",sizeof(struct node2));
//     printf("%d\n",offsetof(struct node2,a));
//     printf("%d\n",offsetof(struct node2,b));
//     printf("%d\n",offsetof(struct node2,arr));
// }   


/***********************************************************************/
//枚举
// enum Day
// {
//     MON = 1,
//     TUE,
//     WED,
//     THU = 6,
//     FRI,
//     SAT,
//     SUN//枚举常量：逗号隔开
// };//仅仅是类型---图纸，当创建了如下变量：da，才占用内存
// // struct node
// // {
// //     int a;//---有类型的变量
// //     enum Day b;
// //     int arr[10];
// // };
// int main()
// {
//     enum Day da = FRI;//从定义的枚举中选择一个枚举常量
//     //枚举常量的值--从0开始，每次递增1
//     printf("%d\n",MON);//原0，修改为1后，从1开始
//     printf("%d\n",TUE);//原1，修改后=2
//     printf("%d\n",WED);//原2，修改后=3

//     //中间修改为6
//     printf("%d\n",THU);
//     printf("%d\n",FRI);
// }


/***********************************************************************/
//联合体
// union test
// {
//     int a;
//     char b;
// };
// int main()
// { 
//     union test t1;
//     t1.a = 0x12345678;
//     printf("%x\n",t1.a);
//     printf("%x\n",t1.b);
//     //地址
//     printf("%p\n",&t1.a);
//     printf("%p\n",&t1.b);
//     //大小
//     printf("%d\n",sizeof(t1));
//     return 0;
// }


/***********************************************************************/
//动态内存管理
// #include <stdlib.h>
// #include <stdio.h>
// #include <string.h>
// #include <errno.h>
//1、malloc函数
// int main()
// {
//     int* p = (int*)malloc(40);
//     if(p == NULL)
//     {
//         printf("%s\n",strerror(errno));
//         return -1;
//     }
//     //内存分配成功，继续走
//     int i = 0;
//     for(i = 0;i<10;i++)
//     {
//         p[i] = i;
//         //or *(p+i) = i;
//     }
//     for( i = 0;i<10;i++)
//     {
//         printf("%d\n",p[i]);
//     }
//}
//2、calloc

//3、realloc
// int main()
// {
//     int* p = (int*)calloc(10,sizeof(int));
//     if(p == NULL)
//     {
//         printf("%s\n",strerror(errno));
//         return -1;
//     }
//     int i = 0;
//     for(i = 0;i<10;i++)
//     {
//         p[i] = i+1;
//     }
//     //扩容
//     int * ptr = (int*)realloc(p,80);//80 = 原来40 + 新增的40
//     if(ptr != NULL)
//     {
//         p = ptr;//继续使用p维护空间
//         ptr = NULL;
//     }
//     //打印
//     for(i = 0;i<10;i++)
//     {
//         printf("%d\n",p[i]);
//     }
//     free(p);
//     p = NULL;
// }


//4、柔性数组
// struct node
// {
//     int a;
//     int arr[];//柔性数组
// };

// int main()
// {
//     struct node* p = (struct node*)malloc(sizeof(struct node)+10*sizeof(int));//大小仅是n的大小
//     if(p == NULL)
//     {
//         printf("%s\n",strerror(errno));
//         return -1;
//     }
//     //调整空间大小，增加40个字节
//     struct node* ptr = (struct node*)realloc(p,sizeof(struct node)+10*sizeof(int)+40);
//     if(ptr != NULL)
//     {
//         p = ptr;
//         ptr = NULL;
//     }
//     //释放空间
//     free(p);
//     p = NULL;
// }


//使用int* arr来开辟空间
// struct node2
// {
//     int a;
//     int * arr;
// };

// int main()
// {
//     struct node2* p = (struct node2*)malloc(sizeof(struct node2));//此处放置堆上，才有可比性。大小有区别：n和指针
//     if(p == NULL)
//     {
//         printf("%s\n",strerror(errno));
//         return -1;
//     }
//     p->arr = (int*)malloc(10*sizeof(int));//两次malloc，释放需注意顺序，从里到外释放
//     //内存空间布局不一致
//     if(p->arr == NULL)
//     {
//         printf("%s\n",strerror(errno));
//     }
//     //释放
//     free(p->arr);
//     free(p);
//     p = NULL;
// }

/***********************************************************************/
//宏定义
// #define MAX(a,b) (a>b?a:b)
// #define PRINT(N) printf("the value of "#N" is %d\n",N)
// //                                        "     "这里面是字符串 
// //同时打印整型和浮点型
// #define PRINT_NUM(N,FORMAT) printf("the value of "#N" is "FORMAT,N)
// //##的作用
// #define ADD_TO_SUM(NUM,VALUE) \
//         sum##NUM+=VALUE//这样的连接必须产生合法的标识符

// //
// #define MAX2(X,Y) ((X)>(Y)?(X):(Y))
// //创建带有类型的MALLOC
// #define MALLOC(NUM,TYPE) (TYPE*)malloc((NUM)*sizeof(TYPE))

// #define __Debug__
// int main()
// {
//     int a = 10;
//     float b = 3.14;
//     int suma = 0;
//     int c = 1;
//     // int b = 20;
//     // printf("%d\n",MAX(a,b));//20
//     // //printf("%d\n",(10>20?10:20));
//     // printf("Hello "        "world\n");//Hello world
//     // PRINT(a);//the value of a is 10
//     // //printf("the value of "#N" is %d\n",N)
//     // //printf("the value of ""a"" is %d\n",a);将#N转换为字符串，即"a"
//     // PRINT(b);//the value of b is 20
//     // //printf("the value of ""b"" is %d\n",b)
//     // PRINT_NUM(a,"%d\n");
//     // PRINT_NUM(b,"%.2f\n");
//     // ADD_TO_SUM(a,10);
//     // int d = MAX2(a++,c++);
//     // //      ((a++)>(c++)?(a++):(c++))
//     // //         10 > 1   ? 11
//     // printf("%d\n",d);
//     // printf("%d\n",a);
//     #ifdef __Debug__
//     printf("debug mode\n");
//     printf("%d\n",c);
//     #endif
//     //int * p = MALLOC(10,int);
// }

// #define M 5
// int main()
// {
//     #if M == 5
//     printf("M is 5\n");
//     #elif M == 10
//     printf("M is 10\n");
//     #else
//     printf("M is not 5 or 10\n");
//     #endif

// }

// #define M 5

// int main()
// {
//     #ifdef M
//     printf("m is defined\n");
//     #endif

//     #ifndef M
//     printf("m is not defined\n");
//     #endif
// }


// #define M(X) X

// int main()
// {
//     #undef M
//     printf("%d\n", M(5));
//     printf("%d\n", 5);
// }


//************************************************************************** */
//offsetof的实现
// #include <stddef.h>
// struct s
// {
//     char a;
//     int b;
//     char c[10];
// };
// #define OFFSETOF(TYPE,M_NAME) (size_t)&(((TYPE*)(0))->M_NAME)
// //强制类型转换为结构体指针，找到其成员
// int main()
// {
//     struct s A = {0};
//     //库
//     // printf("%d\n", offsetof(struct s, c));//8
//     // printf("%d\n", offsetof(struct s, b));//4
//     // printf("%d\n", offsetof(struct s, a));//0
//     //自己的offsetof
//     printf("%d\n", OFFSETOF(struct s, c));
//     printf("%d\n", OFFSETOF(struct s, b));
//     printf("%d\n", OFFSETOF(struct s, a));
// }  

//************************************************************************** */
// int main()
// {
//     char *p="hello world";
//     p = "bit";
//     printf("%s\n",p);
// }

//************************************************************************** */
// #include <stdio.h>
// #include <stdarg.h>

// char buffer[80];
// int vspfunc(char *format, ...)
// {
//    va_list aptr;
//    int ret;

//    va_start(aptr, format);
//    ret = vsprintf(buffer, format, aptr);
//    va_end(aptr);

//    return(ret);
// }

// int main()
// {
//    int i = 5;
//    float f = 27.0;
//    char str[50] = "runoob.com";

//    vspfunc("%d %f %s", i, f, str);
//    //printf("%s\n", buffer);
//    fprintf(stdout, "%s\n", buffer);
//    fflush(stdout);//刷新缓冲区
   
//    return(0);
// }

#include <stdio.h>
#include <string.h>
// 解析串口接收的格式化字符串
void parse_uart_data(const char *recv_buf) {
   int temp, hum;
   float vol;
   
    // 使用sscanf按发送时的格式解析
    // 格式字符串需与发送时的fmt完全匹配
   int ret = sscanf(recv_buf, "temp:%d,hum:%d,vol:%f", &temp, &hum, &vol);
   
    if (ret == 3) {  // 成功解析3个参数
   printf("解析结果:\n");
   printf("温度: %d℃\n", temp);
   printf("湿度: %d%%\n", hum);
   printf("电压: %.2fV\n", vol);
   } else {
   printf("解析失败，格式不匹配\n");
   }
}

// 测试
int main()
{
   char recv_buf[] = "temp:25,hum:60,vol:3.30";  // 模拟串口接收的字节流
   parse_uart_data(recv_buf);
   return 0;
}


